#include "pch.h"
#include"Capture.h"
#include"cts.h"
#include "SystemLog.h"
#include "SystemManager.h"

extern CSystemManager    gSystemMgr;
extern CSystemLog     gSystemLog;

int CTS::init(void) {
	//log("recv CTS init.");
	CString cstrLog;
	DEVINFO	stDevInfo[DEVNUM];
	DWORD nDevCount = 0;
	dirPath.GetCurrentDir(cDir);
	USES_CONVERSION;
	char* c_strPath = T2A(gSystemMgr.m_sGeneralSetting.m_cstrProjectName.GetBuffer());

	sprintf(sensorPath, "%s\\recipe\\%s\\%s_cts.ini", cDir, c_strPath, c_strPath);
	BOOL bRes = 1;

	bRes = Cam_EnumAllDevInfo(stDevInfo, nDevCount, 0);
	cstrLog.Format(L"cam EnumAllDevInfo init result: %d,path:%s", bRes, A2T(sensorPath));
	gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
	//Sleep(100);

	iDevID = stDevInfo[gSystemMgr.m_nCtsId].nDevID;//0304.gai		//0

	cstrLog.Format(L"id=%d,devCount=%d", iDevID, nDevCount);
	gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);

	//if (capturedlg.ChangeGpio) {
	//	bRes = Cam_GPIODir(CTSCam.iDevID, 1, 0);//input model
	//	logdlg.log("Cam GPIO1 Dir 0: %d", bRes);
	//}
	if (gSystemMgr.m_bGpioFlag) {
		//Sleep(100);
		bRes = Cam_SetGPIOOutputValue(iDevID, gSystemMgr.m_nGpioNo, 0);
		bRes = Cam_GPIODir(iDevID, gSystemMgr.m_nGpioNo, 0);
	}

	bRes = Cam_SetConfigEx(iDevID, sensorPath); // 0: success

	iImgWidth = Cam_GetSensorOutputWidth(iDevID);
	iImgHeight = Cam_GetSensorOutputHeight(iDevID);

	cstrLog.Format(L"cam GetSensorOutputWidth result: %d,img w=%d, img h=%d", bRes, iImgWidth, iImgHeight);
	gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
	//Sleep(100);


	BYTE dataformat = 1; // 0:RAW8,1: YUV422, 2:MJPGorRGB24, 3:MIPIRAW10,4:DVPRAW10,5:MIPIRAW12			
	BYTE displayformat = 1; //0: RAW8, 1:RGB24
	BYTE BayerOrder = 1; // 0:RG_GB, 1:GR_BG, 2:GB_RG, 3:BG_GR

	dataformat = Cam_GetSensorDataFormat(iDevID);
	//if (!capturedlg.ChangeGpio) 
	BayerOrder = Cam_GetSensorPixelOrder(iDevID);

	if (bRes == 0) {
		bRes = Cam_BuildPreviewGraph(iDevID, NULL/*HWND_MAIN*/, iImgWidth, iImgHeight, dataformat, displayformat, BayerOrder);
	}
	//logdlg.log("dataformat=%d,order=%d", dataformat, BayerOrder);
	//logdlg.log("dev id:%d, run result: %d", iDevID, bRes);
	//Sleep(100);
	if (bRes == 0)
		return TRUE;
	else
		return 0;
}

int CTS::run()
{
	BOOL bRes = TRUE;
	int result;
	bRes = Cam_MediaControlEx(iDevID, 0); //run
	CString cstrLog;
	cstrLog.Format(L"run --- dev id:%d, run result: %d", iDevID, bRes);
	gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
	if (bRes != 1)
		return bRes;
	result = gSystemMgr.imgCTS.init_iic_by_tool();
	cstrLog.Format(L"run --- dev id:%d, init_iic_by_tool result: %d", iDevID, bRes);
	gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
	if (result = false)
		return result;
	if (gSystemMgr.m_bGpioFlag) {
		bRes = Cam_GPIODir(iDevID, gSystemMgr.m_nGpioNo, 1);
		Sleep(100);
		if (bRes != 1)
			return bRes;
		bRes = Cam_SetGPIOOutputValue(iDevID, gSystemMgr.m_nGpioNo, 1);
		Sleep(100);
		if (bRes != 1)
			return bRes;
		bRes = Cam_SetGPIOOutputValue(iDevID, gSystemMgr.m_nGpioNo,0);
		Sleep(100);
		if (bRes != 1)
			return bRes;
		bRes = Cam_GPIODir(iDevID, gSystemMgr.m_nGpioNo, 0);
	}
	return bRes;
}

int CTS::cap(void)
{
	//log("cap dev.");
	BOOL bRes;

	long buf_size = iImgWidth * iImgHeight * 3;
	bRes = Cam_GrabFrameEx(iDevID, gSystemMgr.imgCap->bImgBuf, &buf_size, 0);
	gSystemMgr.m_dfps = Cam_GetVideoRealTimeFPS(iDevID);//fps
	SetDlgItemTextW(gSystemMgr.m_ptrMainUI->GetSafeHwnd(), IDC_STATIC_103, L"FPS");
	CString fps;
	fps.Format(L"%.1f", gSystemMgr.m_dfps);
	SetDlgItemTextW(gSystemMgr.m_ptrMainUI->GetSafeHwnd(), IDC_STATIC_91, fps);
	if (gSystemMgr.m_dfps >= 25 || gSystemMgr.m_dfps <= 60)
	{
		gSystemMgr.fpsTestResult = true;
	}
	else
	{
		gSystemMgr.fpsTestResult = false;
	}
	//SetDlgItemInt(HWND_MAIN, IDC_FPS, (int)fps, 0);
	//Sleep(20);
	return bRes;
}

int CTS::stop()
{
	BOOL bRes = Cam_MediaControlEx(iDevID, 1);
	CString cstrLog;
	cstrLog.Format(L"CTS stop result:%d", bRes);
	gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
	gSystemMgr.m_dfps = 0;
	CString fps;
	fps.Format(L"%.1f", gSystemMgr.m_dfps);
	SetDlgItemTextW(gSystemMgr.m_ptrMainUI->GetSafeHwnd(), IDC_STATIC_91, fps);
	//if (capturedlg.ChangeGpio) {
	//	bRes = Cam_GPIODir(CTSCam.iDevID, 1, 0);//output model
	//	logdlg.log("Cam GPIO1 Dir 0: %d", bRes);
	//}
	return TRUE;
}

int CTS::destroy()
{
	return TRUE;

}

BOOL CTS::WaitForFirstFrameArrived(DWORD devInst)
{
	gSystemLog.DisplayLogAndSave(L"start search first cam", LV_EVENT);
	int count = 200;
	int err = 0;
	err = Cam_IsFirstFrameArrived(devInst);
	while (!err && count > 0)
	{
		//Cam_MediaControl(iDevID, 1);
		count--;
		Sleep(5);
		err = Cam_IsFirstFrameArrived(devInst);
	}

	CString cstrLog;
	cstrLog.Format(L"end search first cam, count:%d", count);
	gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
	//gSystemLog.DisplayLogAndSave(L"end search first cam", LV_EVENT);
	if (count > 0)
		return TRUE;
	else
		return FALSE;
}

int CTS::init_iic_by_tool(void)
{
	int err = 0;
	CString cstrLog;
	int data[4] = { 0,0,0,0 };
	BYTE subdata[2] = { 0 };
	char ini_path[MAX_PATH] = { 0 };
	char dir[2 * MAX_PATH] = { 0 };
	/*ai_win::get_current_directory(dir);
	sprintf(ini_path, "%s\\recipe\\%s\\init_iic_by_tool.ini", dir, s_aa::recipe_name);*/
	/*log_sys("write ini path: %s", ini_path);*/
	dirPath.GetCurrentDir(cDir);
	USES_CONVERSION;
	char* c_strPath = T2A(gSystemMgr.m_sGeneralSetting.m_cstrProjectName.GetBuffer());
	sprintf(sensorPath, "%s\\recipe\\%s\\init_iic_by_tool.ini", cDir, c_strPath);
	//sprintf(sensorPath, "%s\\recipe\\%s\\%s_cts.ini", cDir, c_strPath, c_strPath);
	cstrLog.Format(L"write ini path: %s", A2T(sensorPath));
	gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);


	FILE* file = fopen(sensorPath, "r");
	if (file == NULL) {
		cstrLog.Format(L"open iic ini file fail");
		gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
		return FALSE;
	}

	char line[5000] = { 0 };
	unsigned char slave = 0;
	int addr = 0;
	char fpga[20];
	int index = 0;
	unsigned char nID = 0x6c;
	while (fgets(line, sizeof(line), file) && index < 5000) {
		if (line[0] == 'f' && (line[1] == 'p' || line[1] == 'g')) {
			sscanf(line, "%s %x %x %x ", &fpga, &data[0], &data[1], &data[2]);
			if (strstr(fpga, "fpga0")) {

				slave = data[0];
				addr = data[1];
				subdata[0] = (data[2] & 0xff);
				//if (GET_CHECKER(HWND_REG_MARK_CHART, IDC_IIC_USE_TOOL))
				//	//err = BurstWriteRegisterEx(slave, (UINT16)addr, subdata, 0, 1);
				//else
				err = Cam_WriteNormalI2CEx(iDevID, slave, addr, 1, subdata, 0);
				if (err != 1)
				{
					cstrLog.Format(L"err=%d, %s 0x%02x, 0x%02x, 0x%02x", fpga, data[0], data[1], data[2]);
					gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
				}
				Sleep(1);
			}
			else if (strstr(fpga, "fpga1")) { //16:8
				Sleep(1);
				slave = data[0];
				addr = data[1];
				subdata[0] = data[2];
				//if (GET_CHECKER(HWND_REG_MARK_CHART, IDC_IIC_USE_TOOL))
				//	//err = BurstWriteRegisterEx(slave, (UINT16)addr, subdata, 1, 1);
				//else
				err = Cam_WriteNormalI2CEx(iDevID, slave, addr, 1, subdata, 2);

				if (err != 1)
				{
					cstrLog.Format(L"err=%d, %s 0x%02x, 0x%04x, 0x%02x", fpga, data[0], data[1], data[2]);
					gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
				}
			}
			else if (strstr(fpga, "fpga2")) { //8:16
				slave = data[0];
				addr = data[1];
				subdata[0] = ((data[2] >> 8) & 0xff);
				subdata[1] = (data[2] & 0xff);
				//if (GET_CHECKER(HWND_REG_MARK_CHART, IDC_IIC_USE_TOOL))
				//	//err = BurstWriteRegisterEx(slave, (UINT16)addr, subdata, 0, 1);
				//else
				err = Cam_WriteNormalI2CEx(iDevID, slave, addr, 2, subdata, 1);
				if (err != 1)
				{
					cstrLog.Format(L"err=%d, %s 0x%02x, 0x%02x, 0x%04x", fpga, data[0], data[1], data[2]);
					gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
				}
				Sleep(10);
			}
			else if (strstr(fpga, "fpga3")) { //16:16
				slave = data[0];
				addr = data[1];
				subdata[0] = ((data[2] >> 8) & 0xff);
				subdata[1] = (data[2] & 0xff);
				//if (GET_CHECKER(HWND_REG_MARK_CHART, IDC_IIC_USE_TOOL))
				//	//err = BurstWriteRegisterEx(slave, (UINT16)addr, subdata, 1, 2);
				//else
				err = Cam_WriteNormalI2CEx(iDevID, slave, addr, 2, subdata, 3);
				if (err != 1)
				{
					cstrLog.Format(L"err=%d, %s 0x%02x, 0x%04x, 0x%04x", fpga, data[0], data[1], data[2]);
					gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
				}
				Sleep(10);
			}
			Sleep(1);
		}
		else if (line[0] == 's' && line[1] == 'l' || line[1] == 'p') { //sleep
			sscanf(line, "%s %d", &fpga, &data[0]);
			cstrLog.Format(L"sleep %d", data[0]);
			gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
			Sleep(data[0]);
		}

		index++;
		Sleep(1);
	}

	fclose(file);
	return TRUE;
}

int CTS::write_iic(void) {
	char line[500] = { 0 };
	int slave = 0;
	int addr = 0;
	char fpga[20];
	int index = 0;
	int err = 0;
	int data[4] = { 0,0,0,0 };
	uint8_t subdata[2] = { 0 };
	CString cstrLog;
	char sensor_name[100] = { 0 };
	char path[MAX_PATH] = { 0 };
	char ini_path[MAX_PATH] = { 0 };
	char dir[2 * MAX_PATH] = { 0 };
	//dirPath.GetCurrentDir(cDir);
	//sprintf(path, "%s\\recipe\\config.ini", dir);
	//read_string_key(path, "system", "default_recipe_setting", sensor_name, sizeof(sensor_name));
	USES_CONVERSION;
	char* c_strPath = T2A(gSystemMgr.m_sGeneralSetting.m_cstrProjectName.GetBuffer());
	sprintf(ini_path, "%s\\recipe\\%s\\register_setting.ini", cDir, c_strPath);

	cstrLog.Format(L"here:%s", A2T(c_strPath));
	gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
	
	cstrLog.Format(L"write ini path: %s", A2T(ini_path));
	gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);

	FILE *file = fopen(ini_path, "r");
	if (file == NULL) {
		gSystemLog.DisplayLogAndSave(L"open iic ini file fail", LV_ERROR);
		return FALSE;
	}

	while (fgets(line, sizeof(line), file) && index < 1000) {
		if (line[0] == 'f' && (line[1] == 'p' || line[1] == 'g')) {
			sscanf(line, "%s %x %x %x ", &fpga, &data[0], &data[1], &data[2]);

			if (strstr(fpga, "fpga0")) {
				//logdlg.log("%s 0x%02x, 0x%02x, 0x%02x", fpga, data[0], data[1], data[2]);

				slave = data[0];
				addr = data[1];
				subdata[0] = (data[2] & 0xff);
				err = Cam_WriteNormalI2CEx(iDevID, slave, addr, 1, subdata, 0);
				if (err != 1) {
					cstrLog.Format(L"write ini err line: %d", index);
					gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
				}
				Sleep(10);
			}
			else if (strstr(fpga, "fpga1")) { //16:8
				//logdlg.log("%s 0x%02x, 0x%04x, 0x%02x", fpga, data[0], data[1], data[2]);

				slave = data[0];
				addr = data[1];
				subdata[0] = data[2];
				err = Cam_WriteNormalI2CEx(iDevID, slave, addr, 1, subdata, 2);
				if (err != 1) {
					cstrLog.Format(L"write ini err line: %d", index);
					gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
				}
				Sleep(10);
			}
			else if (strstr(fpga, "fpga2")) { //8:16
				//logdlg.log("%s 0x%02x, 0x%02x, 0x%04x", fpga, data[0], data[1], data[2]);

				slave = data[0];
				addr = data[1];
				subdata[0] = ((data[2] >> 8) & 0xff);
				subdata[1] = (data[2] & 0xff);
				err = Cam_WriteNormalI2CEx(iDevID, slave, addr, 2, subdata, 1);
				if (err != 1) {
					cstrLog.Format(L"write ini err line: %d", index);
					gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
				}
				Sleep(10);
			}
			else if (strstr(fpga, "fpga3")) { //16:16
				//logdlg.log("%s 0x%02x, 0x%04x, 0x%04x", fpga, data[0], data[1], data[2]);
				slave = data[0];
				addr = data[1];
				subdata[0] = ((data[2] >> 8) & 0xff);
				subdata[1] = (data[2] & 0xff);
				err = Cam_WriteNormalI2CEx(iDevID, slave, addr, 2, subdata, 3);
				if (err != 1) {
					cstrLog.Format(L"write ini err line: %d", index);
					gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
				}
				Sleep(10);
			}

			Sleep(1);
		}
		else if (line[0] == 's' && line[1] == 'l' || line[1] == 'p') { //sleep
			sscanf(line, "%s %d", &fpga, &data[0]);
			cstrLog.Format(L"sleep %d", data[0]);
			gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
			Sleep(data[0]);
		}
		//if (index == 36 || index == 37 || index == 71 || index == 99)
		//	logdlg.log("-------------%s 0x%02x, 0x%04x, 0x%04x", fpga, data[0], data[1], data[2]);
		index++;
		Sleep(1);
	}

	fclose(file);
	return TRUE;
}

int CTS::OVChipInitReadSF(int nID)
{
	int nResult = 0;

	UINT16 addr = 0x8088;
	UINT8 value = 0x08;
	int nReturn = 0;

	addr = 0xa10a;	value = 0x00;
	Cam_WriteNormalI2CEx(iDevID, nID, addr, 1, &value, 2);
	//BurstWriteRegisterEx(nID, addr, &value, 1, 1);

	addr = 0xa11e;	value = 0x7f;
	Cam_WriteNormalI2CEx(iDevID, nID, addr, 1, &value, 2);
	//BurstWriteRegisterEx(nID, addr, &value, 1, 1);

	addr = 0xa11d;	value = 0x00;
	Cam_WriteNormalI2CEx(iDevID, nID, addr, 1, &value, 2);
	//BurstWriteRegisterEx(nID, addr, &value, 1, 1);

	addr = 0xa110;	value = 0x80;
	Cam_WriteNormalI2CEx(iDevID, nID, addr, 1, &value, 2);
	//BurstWriteRegisterEx(nID, addr, &value, 1, 1);

	addr = 0xa10f;	value = 0x18;
	Cam_WriteNormalI2CEx(iDevID, nID, addr, 1, &value, 2);
	//BurstWriteRegisterEx(nID, addr, &value, 1, 1);

	addr = 0xa10e;	value = 0x4c;
	Cam_WriteNormalI2CEx(iDevID, nID, addr, 1, &value, 2);
	//BurstWriteRegisterEx(nID, addr, &value, 1, 1);

	addr = 0xa10d;	value = 0x00;
	Cam_WriteNormalI2CEx(iDevID, nID, addr, 1, &value, 2);
	//BurstWriteRegisterEx(nID, addr, &value, 1, 1);


	///////////////////////////////////////////////////////////////////////////////////////////////////////////////
	return nResult;
}
BOOL CTS::SendHostCmd_Chip(unsigned char nID, unsigned char* pBuf, unsigned int size)
{
	unsigned int   nPageAddr = 0;
	unsigned short nCrcBufOffset = 0;
	unsigned short nCrcCnt = 0;
	unsigned short CalCrc = 0;
	unsigned char  nValue[2];
	unsigned short j = 0;
	unsigned char nSegment = 0;
	unsigned char nTryTime = 0;

	//send host command			
	nCrcBufOffset = 0;
	for (j = 0; j < size; j += Chip_PAGE_SIZE)
	{
		if ((size - j) >= Chip_PAGE_SIZE)
			nSegment = Chip_PAGE_SIZE;
		else
			nSegment = size - j;

		if (size == 10/* && pBuf[0] == 0x81*/)
			nPageAddr = Chip_HOSTCMD_START_ADDR + j;
		else
			nPageAddr = (0xe40b + j);

		Cam_WriteNormalI2CEx(iDevID, nID, nPageAddr, nSegment, (pBuf + j), 2);
		//BurstWriteRegisterEx(nID, nPageAddr, (pBuf + j), 1, nSegment);
	}

	UINT16 addr = 0x8160;
	UINT8 value = 0x01;
	Cam_WriteNormalI2CEx(iDevID, nID, addr, 1, &value, 2);
	//BurstWriteRegisterEx(nID, addr, &value, 1, 1);
	Sleep(60);
	nTryTime = 0;
	nValue[0] = 0x00;
	addr = 0x8180;
	Cam_ReadNormalI2CEx(iDevID, nID, addr, 1, nValue, 2);
	//BurstReadRegisterEx(nID, addr, nValue, 1, 1);

	while (nValue[0] != HOSTCMD_STATUS_DONE)
	{
		Sleep(10);
		nValue[0] = 0x00;
		Cam_ReadNormalI2CEx(iDevID, nID, addr, 1, nValue, 2);
		//BurstReadRegisterEx(nID, addr, nValue, 1, 1);
		nTryTime++;
		if (nTryTime >= 100) {
			gSystemLog.DisplayLogAndSave(L"HOSTCMD_STATUS_DONE err", LV_ERROR);
			//log("HOSTCMD_STATUS_DONE err");
			return FALSE;
		}
	}
	return TRUE;
}
void CTS::GetDataFromDevice_Chip(unsigned char nID, unsigned char* pBuf, unsigned int size)
{
	unsigned int   nPageAddr = 0;
	unsigned short j = 0;
	unsigned char nSegment = 0;

	for (j = 0; j < size; j += Chip_PAGE_SIZE) {
		if ((size - j) >= Chip_PAGE_SIZE) {
			nSegment = Chip_PAGE_SIZE;
		}
		else {
			nSegment = size - j;
		}
		nPageAddr = HOSTCMD_SF_RD_ADDR + j;
		Cam_ReadNormalI2CEx(iDevID, nID, nPageAddr, nSegment, (pBuf + j), 2);
		//BurstReadRegisterEx(nID, nPageAddr, (pBuf + j), 1, nSegment);
	}
}
BOOL CTS::GetFwSector_Chip(unsigned nID, unsigned int nSect, unsigned int nFWoffset, unsigned char* pBuf)
{
	unsigned int   j = 0;
	unsigned short nSegment = 0;
	unsigned char  pCmdBuf[512];

	for (j = 0; j < nSect; j += SF_PAGE_SIZE) {
		if ((nSect - j) >= SF_PAGE_SIZE) {
			nSegment = SF_PAGE_SIZE;
		}
		else {
			nSegment = nSect - j;
		}
		pCmdBuf[0] = HOSTCMD_SF_ID;
		pCmdBuf[1] = HOSTCMD_SF_MODE;
		pCmdBuf[2] = 0x00;
		pCmdBuf[3] = 0x06;
		pCmdBuf[4] = 0x12;
		pCmdBuf[5] = ((nFWoffset + j) >> 16) & 0xff;
		pCmdBuf[6] = ((nFWoffset + j) >> 8) & 0xff;
		pCmdBuf[7] = ((nFWoffset + j) >> 0) & 0xff;
		pCmdBuf[8] = (nSegment >> 8) & 0xff;
		pCmdBuf[9] = (nSegment >> 0) & 0xff;

		UINT8 data = 0x00;
		Cam_WriteNormalI2CEx(iDevID, nID, 0x8181, 1, &data, 2);
		//BurstWriteRegisterEx(nID, 0x8181, &data, 1, 1);

		if (SendHostCmd_Chip(nID, pCmdBuf, (0x0a)) == FALSE) {
			return FALSE;
		}
		else {
			GetDataFromDevice_Chip(nID, pBuf + j, nSegment);
		}
	}
	return TRUE;
}
void GetFwRam_Chip(unsigned nID, unsigned int nSect, unsigned int nFWoffset, unsigned char* pBuf)
{
	unsigned int j = 0;
	unsigned char nSegment = 0;
	unsigned int nPageAddr = 0;

}
void CTS::ReadDataFromDevice(unsigned char nID, unsigned char* pBuf, unsigned int data_start, unsigned int data_size, unsigned char mode)
{
	unsigned int i = 0;
	unsigned int j = 0;
	unsigned int nSect = 0;
	unsigned char nSegment = 0;
	unsigned char nPageSize = 0;
	OVChipInitReadSF(nID);
	for (i = 0; i < data_size; i += SECT_SIZE)
	{
		//log("i=%d", i);
		if ((data_size - i) >= SECT_SIZE)
			nSect = SECT_SIZE;
		else
			nSect = data_size - i;

		if (mode == MODE_ONLY_RAM)
			GetFwRam_Chip(nID, nSect, i + data_start, (pBuf + i));
		else
			GetFwSector_Chip(nID, nSect, i + data_start, (pBuf + i));
	}
}

void CTS::OVChipReboot(int nSlaveID)
{
	//step1: clear watchdog status
	UINT16 addr = OVChip_SYS_BASE + OVChip_SYS_CRSR;
	UINT8 value = 0x00;    //clear all software status
	//BurstWriteRegisterEx(nSlaveID, addr, &value, 1, 1);
	Cam_WriteNormalI2CEx(iDevID, nSlaveID, addr, 1, &value, 2);
	//end of step1

	//step2: enable watchdog to reboot FW from SPI flash
	//clear watchdog count register
	addr = OVChip_SYS_BASE + OVChip_SYS_WDCR;
	UINT8 ndata[4] = { 0 };
	//BurstWriteRegisterEx(nSlaveID, addr, ndata, 1, 4);
	Cam_WriteNormalI2CEx(iDevID, nSlaveID, addr, 4, ndata, 2);

	//set watchdog time period register and enable watchdog, wait for reboot.
	int value32 = (BIT31 + BIT30 + 0x400);
	ndata[3] = (value32 >> 24) & 0xff; ndata[2] = (value32 >> 16) & 0xff; ndata[1] = (value32 >> 8) & 0xff; ndata[0] = value32 & 0xff;
	addr = OVChip_SYS_BASE + OVChip_SYS_WDMR;
	//BurstWriteRegisterEx(nSlaveID, addr, ndata, 1, 4);
	Cam_WriteNormalI2CEx(iDevID, nSlaveID, addr, 4, ndata, 2);
	//end of step2
}

int CTS::read_iic(void) {
	UINT16 addr = 0x8195;
	BYTE value = 0xff;
	unsigned char nID = 0x6c;
	char m_cSN_in[50] = { 0 };
	////Step 1: Boot FW
	//log("start check bootloader");
	//OVChipInitRam(nID);
	////log("burn FW size:%d", sizeof(OV494BurnFW));
	//int nResult = WriteDataToDevice(nID, OVChipBurnFW, 0, sizeof(OVChipBurnFW), MODE_ONLY_RAM);  //download small burn FW into pram	

	//OVChipRunRam(nID);
	////Sleep(1000);	

	//BurstReadRegisterEx(nID, addr, &value, 1, 1);
	//if (value == 0x5a)
	//	log("Run the bootloader successfully.");
	//else
	//	log("Run the bootloader failed[%02x].", value);


	//BYTE pcb_sn[25] = { 0 };
	addr = 0x8000;
	value = 0xff;
	memset(m_cSN_in, 0, sizeof(m_cSN_in));
	ReadDataFromDevice(nID, (unsigned char*)m_cSN_in, addr, 25, MODE_RAM_SPI);
	strcpy(gSystemMgr.m_cInternalSN, m_cSN_in);
	//CString cstrLog;
	//cstrLog.Format(L"read data: %s", (m_cSN_in));
	//gSystemLog.DisplayLogAndSave(cstrLog.GetBuffer(), LV_EVENT);
	Sleep(300);

	//OVChipReboot(nID);		
	return TRUE;
}

int CTS::read_iic_check() {//_check
	int result = true;
	int fw_ver[4] = { 0 };
	int rt;
	int FW_SlaveAdd = 0;
	int FW_regAdd = 0;
	char line[500];
	USES_CONVERSION;
	sprintf(line, "%s", T2A(gSystemMgr.FW_SlaveAdd));
	sscanf(line, "%x", &FW_SlaveAdd);
	sprintf(line, "%s", T2A(gSystemMgr.FW_regAdd));
	sscanf(line, "%x", &FW_regAdd);

	CString cstr;
	cstr.Format(L"FW_SlaveAdd:%d,FW_regAdd:%d", FW_SlaveAdd, FW_regAdd);
	gSystemLog.DisplayLogAndSave(cstr.GetBuffer(), LV_EVENT);

	rt = Cam_ReadNormalI2CEx(iDevID, FW_SlaveAdd, FW_regAdd, 4, gSystemMgr.ver, 2);
	//rt = Cam_ReadNormalI2CEx(dev_id, iic_check.FW_SlaveAdd, iic_check.FW_regAdd, 4, iic_check.ver, 2);
	
	if (gSystemMgr.ver[0] == 0x00 || gSystemMgr.ver[1] == 0x00 || gSystemMgr.ver[2] == 0x00 || gSystemMgr.ver[3] == 0x00) {
		rt = Cam_ReadNormalI2CEx(iDevID, FW_SlaveAdd, FW_regAdd, 4, gSystemMgr.ver, 2);
	}

	cstr.Format(L"read fw addr : %x %x result : %d ver : % 2x, % 2x, % 2x, % 2x", FW_SlaveAdd, FW_regAdd, result, gSystemMgr.ver[0], gSystemMgr.ver[1], gSystemMgr.ver[2], gSystemMgr.ver[3]);
	gSystemLog.DisplayLogAndSave(cstr.GetBuffer(), LV_EVENT);
	
	sprintf(gSystemMgr.checkStr, "%2x%2x%2x%2x", gSystemMgr.ver[0], gSystemMgr.ver[1], gSystemMgr.ver[2], gSystemMgr.ver[3]);
	//log_sys("fw:%s", gSystemMgr.checkStr);
	cstr.Format(L"fw:%s", A2T(gSystemMgr.checkStr));
	gSystemLog.DisplayLogAndSave(cstr.GetBuffer(), LV_EVENT);

	char buffer[100];
	_itoa(gSystemMgr.ver[0], buffer, 16);
		//if (fw_ver[0]== iic_check.ver[0])
		if (!strcmp(buffer, T2A(gSystemMgr.LocalVer[0])))
			SetDlgItemTextA(gSystemMgr.m_ptrIICCheckUI->GetSafeHwnd(), IDC_FV_RESULT, "ok");
		else {
			SetDlgItemTextA(gSystemMgr.m_ptrIICCheckUI->GetSafeHwnd(), IDC_FV_RESULT, "ng");
			result = false;
		}
		SetDlgItemTextA(gSystemMgr.m_ptrIICCheckUI->GetSafeHwnd(), IDC_FIRM_VER, buffer);

		_itoa(gSystemMgr.ver[1], buffer, 16);
		if (!strcmp(buffer, T2A(gSystemMgr.LocalVer[1])))
			SetDlgItemTextA(gSystemMgr.m_ptrIICCheckUI->GetSafeHwnd(), IDC_FV_RESULT2, "ok");
		else {
			SetDlgItemTextA(gSystemMgr.m_ptrIICCheckUI->GetSafeHwnd(), IDC_FV_RESULT2, "ng");
			result = false;
		}
		SetDlgItemTextA(gSystemMgr.m_ptrIICCheckUI->GetSafeHwnd(), IDC_FIRM_VER2, buffer);

		_itoa(gSystemMgr.ver[2], buffer, 16);
		if (!strcmp(buffer, T2A(gSystemMgr.LocalVer[2])))
			SetDlgItemTextA(gSystemMgr.m_ptrIICCheckUI->GetSafeHwnd(), IDC_FV_RESULT3, "ok");
		else {
			SetDlgItemTextA(gSystemMgr.m_ptrIICCheckUI->GetSafeHwnd(), IDC_FV_RESULT3, "ng");
			result = false;
		}

		SetDlgItemTextA(gSystemMgr.m_ptrIICCheckUI->GetSafeHwnd(), IDC_FIRM_VER3, buffer);
		_itoa(gSystemMgr.ver[3], buffer, 16);
		if (!strcmp(buffer, T2A(gSystemMgr.LocalVer[3])))
			SetDlgItemTextA(gSystemMgr.m_ptrIICCheckUI->GetSafeHwnd(), IDC_FV_RESULT4, "ok");
		else {
			SetDlgItemTextA(gSystemMgr.m_ptrIICCheckUI->GetSafeHwnd(), IDC_FV_RESULT4, "ng");
			result = false;
		}

		SetDlgItemTextA(gSystemMgr.m_ptrIICCheckUI->GetSafeHwnd(), IDC_FIRM_VER4, buffer);
	
	return result;
}